package com.own.component.store.redis.configure;

import com.own.component.autoconfig.property.redis.RedisProperties;
import com.own.component.store.core.Store;
import com.own.component.store.core.util.LockStoreUtil;
import com.own.component.store.core.util.RateLimiterUtil;
import com.own.component.store.redis.DefaultRedisStore;
import com.own.component.store.redis.util.RedisLockStoreUtil;
import com.own.component.store.redis.util.RedisRateLimiterUtil;
import org.apache.commons.lang3.StringUtils;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;

import javax.annotation.Resource;

/**
 * StoreRedisConfigure
 *
 * @author chenxueli
 * @date 2023-07-21 11:27:31
 */
@SpringBootConfiguration
public class StoreRedisConfigure {

    @Resource
    private RedisProperties redisProperties;

    @Resource
    private RedissonClient redissonClient;

    @Bean
    public RedissonClient redissonClient() {
        if (redissonClient != null) {
            return redissonClient;
        }
        if (!redisProperties.getEnabled()) {
            return null;
        }
        var config = new Config();
        var c = config.useSingleServer();
        c.setTimeout((int) redisProperties.getTimeout().getSeconds());
        if (StringUtils.isNotBlank(redisProperties.getUsername())) {
            c.setUsername(redisProperties.getUsername());
        }
        if (StringUtils.isNotBlank(redisProperties.getPassword())) {
            c.setPassword(redisProperties.getPassword());
        }
        c.setAddress("redis://" + redisProperties.getHost() + ":" + redisProperties.getPort());
        c.setDatabase(redisProperties.getDatabase());
        // 使用自定义的Fastjson序列化工具
        config.setCodec(new FastjsonCodec());
        redissonClient = Redisson.create(config);
        return redissonClient;
    }

    @Bean
    @ConditionalOnMissingBean(value = Store.class)
    public Store<String> store() {
        return new DefaultRedisStore<>(redissonClient());
    }

    @Bean
    @ConditionalOnMissingBean(value = LockStoreUtil.class)
    public LockStoreUtil lockStoreUtil() {
        return new LockStoreUtil(new RedisLockStoreUtil(redissonClient()));
    }

    @Bean
    @ConditionalOnMissingBean(value = RateLimiterUtil.class)
    public RateLimiterUtil rateLimiterUtil() {
        return new RedisRateLimiterUtil(redissonClient());
    }


}
